package com.appspot.mercadobgbr.client;

import com.appspot.mercadobgbr.client.JogoList.JogoRow;
import com.appspot.mercadobgbr.shared.BoardGame;
import com.appspot.mercadobgbr.shared.Email;
import com.appspot.mercadobgbr.shared.Item;
import com.appspot.mercadobgbr.shared.Usuario;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class MercadoBGBR implements EntryPoint {

	public class Controller {

		public void addNewJogo(BoardGame currentJogo) {
			Item item = new Item(currentJogo);
			persistJogo(jogoList.addJogoToUi(item, null));
			goToJogoList();
		}

		public void updateJogo(BoardGame currentJogo) {
			Item item = new Item(currentJogo);
			persistJogo(jogoList.updateItem(item));
			goToJogoList();
		}
		
		protected void emailEnviado(String idItem) {
			jogoList.emailEnviado(idItem);
			
		}


		public void venderJogo(BoardGame currentJogo) {
			JogoRow removeItem = jogoList.removeItem(new Item(currentJogo));
			removeItem.getJogoData().getBoardGame().setVendido(true);
			persistJogo(removeItem);
			goToJogoList();
		}

		public String getEmailUsuario() {
			return jogoList.getUsuario().getEmail();
		}

		public String getNicknameUsuario() {
			return jogoList.getUsuario().getNickname();
		}

		public Usuario getUsuario() {
			return jogoList.getUsuario();
		}

		public void goToJogoDetails() {
			uiPages.doPageTransition(jogoDetails.getPageIndex());
		}

		public void goToUsuarioDetails() {
			uiPages.doPageTransition(usuarioDetails.getPageIndex());
		}

		public void goToJogoList() {
			uiPages.doPageTransition(jogoList.getPageIndex());
		}

		public void loadJogo(Item data) {
			jogoDetails.view(data == null ? null : data.getBoardGame());
		}

		public void loadUsuario(Usuario usuario) {
			usuarioDetails.view(usuario);
		}

		public void persistJogo(final JogoRow row) {
			apiJogo.persistJogo(row.getJogoData().getBoardGame(), new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					DomUtils.getWindow().alert("Falhou ao tentar salvar item. Tente novamente.");
				}

				public void onSuccess(String result) {
					if (result == null) {
						onFailure(null);
					} else {
						row.setRowAsPersisted(result);
					}
				}

			});
		}

		public void getBoardGame(BoardGame potentialJogo) {
			apiJogo.getBoardGame(potentialJogo, new AsyncCallback<BoardGame[]>() {

				public void onFailure(Throwable caught) {
					jogoDetails.setBoardGame(null);
				}

				public void onSuccess(BoardGame[] boardGames) {
					if (boardGames == null) {
						onFailure(null);
					} else {
						if (boardGames.length == 1 && boardGames[0].getThumb() != null
								&& !boardGames[0].getThumb().equals("")) {
							jogoDetails.setBoardGame(boardGames[0]);
						} else {
							jogoDetails.setBoardGames(boardGames);
						}

					}
				}
			});

		}

		public void updateUsuario(Usuario usuario) {
			apiJogo.persistUsuario(usuario, new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					DomUtils.getWindow().alert(
							"Falhou ao tentar salvar os dados do Usuario. Favor tentar novamente.");
				}

				public void onSuccess(String result) {
					if (result == null) {
						onFailure(null);
					} else {
						goToJogoList();
					}
				}

			});

		}

		public void enviarEmail(Email email) {
			apiJogo.enviarEmail(email, new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					DomUtils.getWindow().alert("Falhou ao enviar e-mail. Favor tentar novamente.");
					jogoDetails.emailButton.setDisabled(false);
					jogoDetails.emailButton.setInnerText("E-mail enviado");
				}

				public void onSuccess(String result) {
					if (result == null) {
						onFailure(null);
					} else {
						DomUtils.getWindow().alert("E-mail enviado com sucesso!");
						emailEnviado(result);
						goToJogoList();
					}
				}

			});
		}

		
	}

	public interface Resources extends JogoList.Resources, JogoDetails.Resources,
			UsuarioDetails.Resources {
	}

	private final JogosApiAsync apiJogo = GWT.create(JogosApi.class);;
	private final Resources resources = GWT.create(Resources.class);
	private JogoDetails jogoDetails;
	private UsuarioDetails usuarioDetails;
	private JogoList jogoList;
	private PageTransitionPanel uiPages;

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		StyleInjector.injectAtEnd(resources.jogoDetailsCss().getText()
				+ resources.jogoListCss().getText() + resources.controlBarCss().getText()
				+ resources.usuarioDetailsCss().getText());

		uiPages = new PageTransitionPanel(Document.get().getBody());
		Controller controller = new Controller();

		ControlBar.Controls jogoListControls = JogoList.createControls(controller, resources);
		jogoList = new JogoList(uiPages, jogoListControls, controller, resources);

		ControlBar.Controls jogoDetailsControls = JogoDetails.createControls(controller, resources);
		jogoDetails = new JogoDetails(uiPages, jogoDetailsControls, controller, resources);

		ControlBar.Controls usuarioDetailsControls = UsuarioDetails.createControls(controller,
				resources);
		usuarioDetails = new UsuarioDetails(uiPages, usuarioDetailsControls, controller, resources);

		carregaUsuario();

		uiPages.doResize();

		DeferredCommand.defer(new DeferredCommand() {
			@Override
			public void onExecute() {
				uiPages.doResize();
			}
		}, 100);

	}

	/**
	 * Carrega Usuario e Partidas
	 */
	private void carregaUsuario() {
		DeferredCommand.defer(new DeferredCommand() {
			@Override
			public void onExecute() {
				if (!jogoList.isLoggedIn()) {
					jogoList.notifyNotLoggedIn(null);
				}
			}
		}, 5000);

		// apiJogo.getJogoList(new AsyncCallback<Jogo[]>() {
		apiJogo.getItemList(new AsyncCallback<Item[]>() {

			public void onFailure(Throwable caught) {
				if (caught == null) {
					apiJogo.getLoginUrl(new AsyncCallback<String>() {

						public void onFailure(Throwable caught) {
							jogoList.notifyNotLoggedIn(null);
						}

						public void onSuccess(String loginUrl) {
							jogoList.notifyNotLoggedIn(loginUrl);
						}

					});
				} else {
					jogoList.notifyNotLoggedIn(null);
				}
			}

			public void onSuccess(Item[] itens) {
				if (itens == null) {
					onFailure(null);
				} else {
					Usuario usuario = itens[0].getUsuario();
					jogoList.setUsuario(usuario);
					jogoList.setUserLoggedIn();

					for (int i = 1, n = itens.length; i < n; i++) {
						Item item = itens[i];
						jogoList.addJogoToUi(item, null).setRowAsPersisted(
								item.getBoardGame().getId());
					}
				}
			}
		});
	}
}
